﻿using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Media.Imaging;
using GurLoader.Preferences;
using GurLoader.Screenshot;
using GurLoader.Service.ImgurTaskBuilder;
using GurLoader.Service.TaskExecution;
using GurLoader.Util;
using GurLoader.View;
using GurLoader.ViewModel;
using Point = System.Drawing.Point;

namespace GurLoader.Service.ScreenshotUpload
{
    public class ScreenshotUploadService : IScreenshotUploadService
    {
        private ITaskBuilderService ImgurTaskBuilderService { get; set; }
        private ITaskExecutionService ExecutionService { get; set; }
        private IViewBuilder ViewBuilder { get; set; }
        private IDispatcher Dispatcher { get; set; }
        private ICommandManager CommandManager { get; set; }
        private GurLoaderPreferences AppPreferences { get; set; }

        public ScreenshotUploadService(ITaskBuilderService imgurTaskBuilderService, 
            ITaskExecutionService executionService, IViewBuilder viewBuilder, IDispatcher dispatcher,
            ICommandManager commandManager, GurLoaderPreferences preferences)
        {
            if ( imgurTaskBuilderService == null )
                throw new ArgumentNullException("imgurTaskBuilderService");

            if ( executionService == null )
                throw new ArgumentNullException("executionService");

            if (viewBuilder == null)
                throw new ArgumentNullException("viewBuilder");

            if (dispatcher == null)
                throw new ArgumentNullException("dispatcher");

            if (commandManager == null)
                throw new ArgumentNullException("commandManager");

            if (preferences == null)
                throw new ArgumentNullException("preferences");

            ImgurTaskBuilderService = imgurTaskBuilderService;
            ExecutionService = executionService;
            ViewBuilder = viewBuilder;
            Dispatcher = dispatcher;
            CommandManager = commandManager;
            AppPreferences = preferences;
        }

        public void UploadFullScreen()
        {
            ScreenshotCapture sc = new ScreenshotCapture();
            
            Rectangle totalSize = Rectangle.Empty;

            foreach (Screen s in Screen.AllScreens)
                totalSize = Rectangle.Union(totalSize, s.Bounds);

            Point source = new Point(totalSize.X, totalSize.Y);
            Point dest = new Point(0,0);
            
            
            Image img = sc.CaptureImage(source, dest, totalSize);

            var progress = new Progress<IDelegatingCommandProgress>();
            var ctSource = new CancellationTokenSource();
            var task = ImgurTaskBuilderService.UploadImages(new[] { new ImageContent(img, "Screenshot image") }, progress, ctSource.Token, true, Dispatcher, AppPreferences.OpenWhenComplete);

            ExecutionService.ExecuteTask(task, progress, ctSource, CommandManager);
        }

        public void UploadScreenArea( IDispatcher dispatcher, bool invokeRequired )
        {
            Rectangle totalSize = Rectangle.Empty;

            foreach (Screen s in Screen.AllScreens)
                totalSize = Rectangle.Union(totalSize, s.Bounds);

            Point source = new Point(totalSize.X, totalSize.Y);
            Point dest = new Point(0, 0);

            ScreenshotCapture sc = new ScreenshotCapture();
            
            Image img = sc.CaptureImage(source, dest, totalSize);

            BitmapSource imgSource = Imaging.CreateBitmapSourceFromBitmap(img, dispatcher, invokeRequired);
            CaptureAreaViewModel vm = new CaptureAreaViewModel(imgSource);

            Point? selectionStart = null;
            Point? selectionEnd = null;

            vm.AreaSelected += (sender, e) =>
            {
                selectionStart = new Point(Convert.ToInt32(vm.SelectionStart.X), Convert.ToInt32(vm.SelectionStart.Y));
                selectionEnd = new Point(Convert.ToInt32(vm.SelectionEnd.X), Convert.ToInt32(vm.SelectionEnd.Y));
            };

            var window = ViewBuilder.CreateCaptureAreaWindow(vm, totalSize.Top, totalSize.Left, totalSize.Width,
                totalSize.Height);

            if ( selectionStart != null && selectionStart.HasValue && selectionEnd != null && selectionEnd.HasValue)
            {
                Rectangle cropRect = new Rectangle(
                    selectionStart.Value.X,
                    selectionStart.Value.Y,
                    selectionEnd.Value.X - selectionStart.Value.X,
                    selectionEnd.Value.Y - selectionStart.Value.Y);

                Bitmap sourceBitmap = new Bitmap(img);
                Bitmap cropped = sourceBitmap.Clone(cropRect, sourceBitmap.PixelFormat);
                
                var progress = new Progress<IDelegatingCommandProgress>();
                var ctSource = new CancellationTokenSource();
                var task = ImgurTaskBuilderService.UploadImages(new[] { new ImageContent(cropped, "Screenshot image") }, progress, ctSource.Token, true, Dispatcher, AppPreferences.OpenWhenComplete);

                ExecutionService.ExecuteTask(task, progress, ctSource, CommandManager);
            }
        }
    }
}
